import { Readable } from "node:stream" // Node.js 流模块

import type { FastifyInstance, FastifyReply } from "fastify"

import { createFollowClient } from "~/lib/api-client" // API 客户端创建函数

// 导入不同类型的 OG 渲染器
import { renderFeedOG } from "./feed"
import { renderListOG } from "./list"
import { renderUserOG } from "./user"

// 注册 Open Graph 路由
export const ogRoute = (app: FastifyInstance) => {
  app.get("/og/:type/:id", async (req, reply) => {
    const { type, id } = req.params as Record<string, string>

    // 创建 API 客户端
    const apiClient = createFollowClient()
    let imageRes: {
      image: Buffer
      contentType: string
    } | null = null

    // 创建错误处理函数
    const errorFallback = createErrorFallback(reply)

    // 根据类型渲染不同的 OG 图片
    switch (type) {
      case "feed": {
        imageRes = await renderFeedOG(apiClient, id!).catch(errorFallback)
        break
      }
      case "user": {
        imageRes = await renderUserOG(apiClient, id!).catch(errorFallback)
        break
      }
      case "list": {
        imageRes = await renderListOG(apiClient, id!).catch(errorFallback)
        break
      }
      default: {
        return reply.code(404).send("Not found")
      }
    }

    // 处理渲染失败的情况
    if (!imageRes) {
      if (!reply.sent) {
        return reply.code(404).send("Not found")
      }
      return
    }

    // 创建可读流发送图片
    const stream = new Readable({
      read() {
        this.push(imageRes!.image)
        this.push(null)
      },
    })

    // 设置响应头和缓存控制
    reply.type(imageRes.contentType).headers({
      "Cache-Control": "max-age=3600, s-maxage=3600, stale-while-revalidate=600",
      "Cloudflare-CDN-Cache-Control": "max-age=3600, s-maxage=3600, stale-while-revalidate=600",
      "CDN-Cache-Control": "max-age=3600, s-maxage=3600, stale-while-revalidate=600",
    })
    return reply.send(stream)
  })
}

// 创建错误处理回调
const createErrorFallback = (reply: FastifyReply) => (code: number | Error) => {
  if (typeof code !== "number" && code instanceof Error) {
    reply.code(500).send(code.message)
    return null
  }
  let message = "Internal server error"
  if (code === 404) {
    message = "Not found"
  }
  reply.code(code).send(message)
  return null
}
